package com.yami.shop.manager.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.app.dto.ProductDto;
import com.yami.shop.bean.app.dto.ShopCartItemDto;
import com.yami.shop.bean.dto.DerivativeCategoryDto;
import com.yami.shop.bean.model.*;
import com.yami.shop.bean.param.StockBillExportParam;
import com.yami.shop.bean.vo.*;
import com.yami.shop.common.bean.LangConfig;
import com.yami.shop.common.bean.LangItemConfig;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.config.ShopConfig;
import com.yami.shop.service.*;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 统一语言工具
 *
 * @author LGH
 */
@Service
@AllArgsConstructor
public class LangManager {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private final ShopConfig shopConfig;

    private final ProdLangService prodLangService;

    private final SkuLangService skuLangService;

    private final BrandLangService brandLangService;

    private final CategoryLangService categoryLangService;

    private final ProdPropLangService prodPropLangService;

    private final ProdPropValueLangService prodPropValueLangService;

    private final ProdParameterLangService prodParameterLangService;

    private final StockChangeReasonLangService stockChangeReasonLangService;


    /**
     * ======================================= 商品 =======================================
     */

    public void getProdLang(List<Product> prodList) {
        if (CollUtil.isEmpty(prodList)) {
            return;
        }
        getProdAndLang(prodList);
        for (Product product : prodList) {
            product.setProdLangList(null);
            if (CollUtil.isEmpty(product.getSkuList())) {
                continue;
            }
            for (Sku sku : product.getSkuList()) {
                sku.setSkuLangList(null);
            }
        }
    }

    public void getProdAndLang(Product product) {
        getProdAndLang(Collections.singletonList(product));
    }

    public void getProdAndLang(List<Product> prodList) {
        if (CollUtil.isEmpty(prodList)) {
            return;
        }
        List<Sku> skuList = new ArrayList<>();
        List<Long> ids = new ArrayList<>();
        for (Product product : prodList) {
            ids.add(product.getProdId());
            if (CollUtil.isEmpty(product.getSkuList())) {
                continue;
            }
            skuList.addAll(product.getSkuList());
        }
        LangConfig langConfig = this.getLangConfig();

        List<ProdLang> list = prodLangService.list(new LambdaQueryWrapper<ProdLang>().in(ProdLang::getProdId , ids));
        Map<Long, List<ProdLang>> langMap = list.stream().collect(Collectors.groupingBy(ProdLang::getProdId));
        for (Product product : prodList) {
            List<ProdLang> langList = langMap.get(product.getProdId());
            if (CollUtil.isEmpty(langList)) {
                continue;
            }
            Map<Integer, ProdLang> map = langList.stream().filter(item -> Objects.nonNull(item.getLang())).collect(Collectors.toMap(ProdLang::getLang, o -> o));
            ProdLang prodLang = map.get(getLang(map.keySet(), langConfig, I18nMessage.getLang()));
            product.setProdName(prodLang.getProdName());
            product.setBrief(prodLang.getBrief());
            product.setContent(prodLang.getContent());
            product.setProdLangList(langList);
        }

        if (CollUtil.isNotEmpty(skuList)) {
            this.getSkuAndLang(skuList);
        }
    }

    public void getProdDtoLang(List<ProductDto> prodList) {
        if (CollUtil.isEmpty(prodList)) {
            return;
        }
        List<Long> ids = new ArrayList<>();
        for (ProductDto product : prodList) {
            ids.add(product.getProdId());
        }

        Map<Long, ProdLang> prodLangMap = this.getProdLangMap(ids);
        for (ProductDto product : prodList) {
            ProdLang prodLang = prodLangMap.get(product.getProdId());
            product.setProdName(prodLang.getProdName());
            product.setBrief(prodLang.getBrief());
//            product.setContent(prodLang.getContent());
        }
    }

    private ProdLang getProdLang(LangConfig langConfig, List<ProdLang> prodLangList, Integer lang) {
        if (CollUtil.isEmpty(prodLangList)) {
            return null;
        }
        Map<Integer, ProdLang> map = prodLangList.stream().filter(item -> Objects.nonNull(item.getLang())).collect(Collectors.toMap(ProdLang::getLang, o -> o));
        ProdLang prodLang = map.get(getLang(map.keySet(), langConfig, lang));
        return prodLang;
    }

    public Map<Long, ProdLang> getProdLangMap(List<Long> prodIds) {
        Map<Long, ProdLang> prodMap = new HashMap<>();
        if (CollUtil.isEmpty(prodIds)) {
            return prodMap;
        }
        LangConfig langConfig = this.getLangConfig();

        List<ProdLang> list = prodLangService.list(new LambdaQueryWrapper<ProdLang>().in(ProdLang::getProdId , prodIds));
        Map<Long, List<ProdLang>> langMap = list.stream().collect(Collectors.groupingBy(ProdLang::getProdId));
        for (Long prodId : prodIds) {
            List<ProdLang> langList = langMap.get(prodId);
            if (CollUtil.isEmpty(langList)) {
                continue;
            }
            Map<Integer, ProdLang> map = langList.stream().filter(item -> Objects.nonNull(item.getLang())).collect(Collectors.toMap(ProdLang::getLang, o -> o));
            ProdLang prodLang = map.get(getLang(map.keySet(), langConfig, I18nMessage.getLang()));
            prodMap.put(prodId, prodLang);
        }
        return prodMap;
    }


    public void handleProdLang(Product product) {
        handleProdLang(Collections.singletonList(product));
    }

    public void handleProdLang(List<Product> prodList) {
        if (CollUtil.isEmpty(prodList)) {
            return;
        }
        Integer lang = I18nMessage.getLang();
        LangConfig langConfig = this.getLangConfig();
        for (Product product : prodList) {
            if (CollUtil.isEmpty(product.getProdLangList())) {
                continue;
            }
            ProdLang prodLang = getProdLang(langConfig, product.getProdLangList(), lang);
            product.setProdName(prodLang.getProdName());
            product.setBrief(prodLang.getBrief());
            product.setContent(prodLang.getContent());
            if (CollUtil.isEmpty(product.getSkuList())) {
                continue;
            }
            for (Sku sku : product.getSkuList()) {
                if (CollUtil.isEmpty(sku.getSkuLangList())) {
                    continue;
                }
                SkuLang skuLang = getSkuLang(langConfig, sku.getSkuLangList(), lang);
                sku.setSkuName(skuLang.getSkuName());
                sku.setProdName(skuLang.getProdName());
                sku.setProperties(skuLang.getProperties());
            }
        }

    }


    /**
     * ======================================= sku =======================================
     */

    public void getSkuLang(List<Sku> skuList) {
        if (CollUtil.isEmpty(skuList)) {
            return;
        }
        this.getSkuAndLang(skuList);
        for (Sku sku : skuList) {
            sku.setSkuLangList(null);
        }
    }

    public void getSkuAndLang(Sku sku) {
        this.getSkuAndLang(Collections.singletonList(sku));
    }

    public void getSkuAndLang(List<Sku> skuList) {
        if (CollUtil.isEmpty(skuList)) {
            return;
        }
        LangConfig langConfig = this.getLangConfig();

        List<Long> ids = skuList.stream().map(Sku::getSkuId).collect(Collectors.toList());
        List<SkuLang> list = skuLangService.list(new LambdaQueryWrapper<SkuLang>().in(SkuLang::getSkuId , ids));
        Map<Long, List<SkuLang>> langMap = list.stream().collect(Collectors.groupingBy(SkuLang::getSkuId));
        for (Sku sku : skuList) {
            List<SkuLang> langList = langMap.get(sku.getSkuId());
            if (CollUtil.isEmpty(langList)) {
                continue;
            }
            Map<Integer, SkuLang> map = langList.stream().filter(item -> Objects.nonNull(item.getLang())).collect(Collectors.toMap(SkuLang::getLang, o -> o));
            SkuLang skuLang = map.get(getLang(map.keySet(), langConfig, I18nMessage.getLang()));
            sku.setProdName(skuLang.getProdName());
            sku.setSkuName(skuLang.getSkuName());
            sku.setProperties(skuLang.getProperties());
            sku.setSkuLangList(langList);
        }
    }

    public void getProdNameToSku(Sku sku) {
        this.getProdNameToSku(Collections.singletonList(sku));
    }

    public void getProdNameToSku(List<Sku> skuList) {
        if (CollUtil.isEmpty(skuList)) {
            return;
        }
        LangConfig langConfig = this.getLangConfig();

        List<Long> ids = skuList.stream().map(Sku::getProdId).collect(Collectors.toList());
        List<ProdLang> list = prodLangService.list(new LambdaQueryWrapper<ProdLang>().in(ProdLang::getProdId , ids));
        Map<Long, List<ProdLang>> langMap = list.stream().collect(Collectors.groupingBy(ProdLang::getProdId));
        for (Sku sku : skuList) {
            List<ProdLang> langList = langMap.get(sku.getProdId());
            if (CollUtil.isEmpty(langList)) {
                continue;
            }
            Map<Integer, ProdLang> map = langList.stream().filter(item -> Objects.nonNull(item.getLang())).collect(Collectors.toMap(ProdLang::getLang, o -> o));
            ProdLang prodLang = map.get(getLang(map.keySet(), langConfig, I18nMessage.getLang()));
            sku.setProdName(prodLang.getProdName());
        }
    }


    public Map<Long, SkuLang> getSkuLangMap(List<Long> skuIds) {
        Map<Long, SkuLang> skuMap = new HashMap<>();
        if (CollUtil.isEmpty(skuIds)) {
            return skuMap;
        }
        LangConfig langConfig = this.getLangConfig();

        List<SkuLang> list = skuLangService.list(new LambdaQueryWrapper<SkuLang>().in(SkuLang::getSkuId , skuIds));
        Map<Long, List<SkuLang>> langMap = list.stream().collect(Collectors.groupingBy(SkuLang::getSkuId));
        for (Long skuId : skuIds) {
            List<SkuLang> langList = langMap.get(skuId);
            if (CollUtil.isEmpty(langList)) {
                continue;
            }
            Map<Integer, SkuLang> map = langList.stream().filter(item -> Objects.nonNull(item.getLang())).collect(Collectors.toMap(SkuLang::getLang, o -> o));
            SkuLang skuLang = map.get(getLang(map.keySet(), langConfig, I18nMessage.getLang()));
            skuMap.put(skuId, skuLang);
        }
        return skuMap;
    }

    private SkuLang getSkuLang(LangConfig langConfig, List<SkuLang> skuLangList, Integer lang) {
        if (CollUtil.isEmpty(skuLangList)) {
            return null;
        }
        Map<Integer, SkuLang> map = skuLangList.stream().filter(item -> Objects.nonNull(item.getLang())).collect(Collectors.toMap(SkuLang::getLang, o -> o));
        SkuLang skuLang = map.get(getLang(map.keySet(), langConfig, lang));
        return skuLang;
    }

    public void handleSkuLang(List<Sku> skuList) {
        if (CollUtil.isEmpty(skuList)) {
            return;
        }
        handleSkuAndLang(skuList);
        for (Sku sku : skuList) {
            sku.setSkuLangList(null);
        }
    }

    public void handleSkuAndLang(Sku sku) {
        this.handleSkuAndLang(Collections.singletonList(sku));
    }

    public void handleSkuAndLang(List<Sku> skuList) {
        if (CollUtil.isEmpty(skuList)) {
            return;
        }
        Integer lang = I18nMessage.getLang();
        LangConfig langConfig = this.getLangConfig();
        for (Sku sku : skuList) {
            if (CollUtil.isEmpty(sku.getSkuLangList())) {
                continue;
            }
            SkuLang skuLang = getSkuLang(langConfig, sku.getSkuLangList(), lang);
            sku.setSkuName(skuLang.getSkuName());
            sku.setProdName(skuLang.getProdName());
            sku.setProperties(skuLang.getProperties());
        }
    }

    /**
     * ======================================= 分类 =======================================
     */

    public void getCategoryLang(List<Category> categories) {
        if (CollUtil.isEmpty(categories)) {
            return;
        }
        getCategoryAndLang(categories);
        for (Category category : categories) {
            category.setCategoryLangList(null);
        }
    }

    public void getCategoryAndLang(Category category) {
        getCategoryAndLang(Collections.singletonList(category));
    }

    public void getCategoryAndLang(List<Category> categories) {
        if (CollUtil.isEmpty(categories)) {
            return;
        }
        Integer lang = I18nMessage.getLang();
        LangConfig langConfig = this.getLangConfig();

        List<Long> ids = categories.stream().map(Category::getCategoryId).collect(Collectors.toList());
        List<CategoryLang> list = categoryLangService.list(new LambdaQueryWrapper<CategoryLang>().in(CategoryLang::getCategoryId , ids));
        Map<Long, List<CategoryLang>> langMap = list.stream().collect(Collectors.groupingBy(CategoryLang::getCategoryId));
        for (Category category : categories) {
            List<CategoryLang> categoryLangList = langMap.get(category.getCategoryId());
            if (CollUtil.isEmpty(categoryLangList)) {
                continue;
            }
            CategoryLang categoryLang = getCategoryLang(langConfig, categoryLangList, category.getCategoryId(), lang);
            category.setCategoryName(categoryLang.getCategoryName());
            category.setCategoryLangList(categoryLangList);
        }
    }

    public void getCategoryShopVOAndLang(List<CategoryShopVO> categories) {
        if (CollUtil.isEmpty(categories)) {
            return;
        }
        LangConfig langConfig = this.getLangConfig();
        Integer lang = I18nMessage.getLang();
        List<Long> categoryIds = new ArrayList<>();
        for (CategoryShopVO category : categories) {
            categoryIds.add(category.getCategoryId());
            categoryIds.add(category.getParentId());
        }
        List<CategoryLang> list = categoryLangService.list(new LambdaQueryWrapper<CategoryLang>().in(CategoryLang::getCategoryId , categoryIds));
        Map<Long, List<CategoryLang>> langMap = list.stream().collect(Collectors.groupingBy(CategoryLang::getCategoryId));
        for (CategoryShopVO category : categories) {
            CategoryLang categoryLang = getCategoryLang(langConfig, langMap, category.getCategoryId(),lang);
            if (Objects.nonNull(categoryLang)) {
                category.setName(categoryLang.getCategoryName());
                category.setCategoryLangList(langMap.get(category.getCategoryId()));
            }

            CategoryLang parentCategoryLang = getCategoryLang(langConfig, langMap, category.getParentId(), lang);
            if (Objects.nonNull(parentCategoryLang)) {
                category.setParentName(parentCategoryLang.getCategoryName());
                category.setParentCategoryLangList(langMap.get(category.getParentId()));
            }
        }
    }
    public void handleCategoryShopVOLang(List<CategoryShopVO> categories) {
        if (CollUtil.isEmpty(categories)) {
            return;
        }
        Integer lang = I18nMessage.getLang();
        LangConfig langConfig = this.getLangConfig();
        for (CategoryShopVO category : categories) {
            if (CollUtil.isNotEmpty(category.getCategoryLangList())) {
                CategoryLang categoryLang = getCategoryLang(langConfig, category.getCategoryLangList(), lang);
                category.setName(categoryLang.getCategoryName());
                category.setCategoryLangList(null);
            }
            if (CollUtil.isNotEmpty(category.getParentCategoryLangList())) {
                CategoryLang categoryLang = getCategoryLang(langConfig, category.getParentCategoryLangList(), lang);
                category.setParentName(categoryLang.getCategoryName());
                category.setParentCategoryLangList(null);
            }
        }
    }

    private CategoryLang getCategoryLang(LangConfig langConfig, Map<Long, List<CategoryLang>> langMap, Long categoryId, Integer lang) {
        List<CategoryLang> langList = langMap.get(categoryId);
        if (CollUtil.isEmpty(langList)) {
            return null;
        }
        Map<Integer, CategoryLang> map = langList.stream().filter(item -> Objects.nonNull(item.getLang())).collect(Collectors.toMap(CategoryLang::getLang, o -> o));
        CategoryLang categoryLang = map.get(getLang(map.keySet(), langConfig, lang));
        return categoryLang;
    }

    private CategoryLang getCategoryLang(LangConfig langConfig, List<CategoryLang> categoryLangList, Long categoryId, Integer lang) {
        if (CollUtil.isEmpty(categoryLangList)) {
            return null;
        }
        Map<Integer, CategoryLang> map = categoryLangList.stream().filter(item -> Objects.nonNull(item.getLang())).collect(Collectors.toMap(CategoryLang::getLang, o -> o));
        CategoryLang categoryLang = map.get(getLang(map.keySet(), langConfig, lang));
        return categoryLang;
    }

    public Map<Long, CategoryLang> getCategoryLangMap(List<Long> categoryIds) {
        Map<Long, CategoryLang> categoryMap = new HashMap<>();
        if (CollUtil.isEmpty(categoryIds)) {
            return categoryMap;
        }
        LangConfig langConfig = this.getLangConfig();

        List<CategoryLang> list = categoryLangService.list(new LambdaQueryWrapper<CategoryLang>().in(CategoryLang::getCategoryId , categoryIds));
        Map<Long, List<CategoryLang>> langMap = list.stream().collect(Collectors.groupingBy(CategoryLang::getCategoryId));
        for (Long categoryId : categoryIds) {
            List<CategoryLang> langList = langMap.get(categoryId);
            if (CollUtil.isEmpty(langList)) {
                continue;
            }
            Map<Integer, CategoryLang> map = langList.stream().filter(item -> Objects.nonNull(item.getLang())).collect(Collectors.toMap(CategoryLang::getLang, o -> o));
            CategoryLang categoryLang = map.get(getLang(map.keySet(), langConfig, I18nMessage.getLang()));
            categoryMap.put(categoryId, categoryLang);
        }
        return categoryMap;
    }

    public void handleCategoryLang(List<Category> categories) {
        if (CollUtil.isEmpty(categories)) {
            return;
        }
        LangConfig langConfig = this.getLangConfig();
        Integer lang = I18nMessage.getLang();
        for (Category category : categories) {
            if (CollUtil.isNotEmpty(category.getCategoryLangList())) {
                CategoryLang categoryLang = getCategoryLang(langConfig, category.getCategoryLangList(), lang);
                category.setCategoryName(categoryLang.getCategoryName());
                category.setCategoryLangList(null);
            }
            if (CollUtil.isEmpty(category.getCategories())) {
                continue;
            }
            for (DerivativeCategoryDto derivativeCategory : category.getCategories()) {
                CategoryLang categoryLang = getCategoryLang(langConfig, derivativeCategory.getCategoryLangList(), lang);
                derivativeCategory.setCategoryName(categoryLang.getCategoryName());
                derivativeCategory.setCategoryLangList(null);
            }
        }
    }

    private CategoryLang getCategoryLang(LangConfig langConfig, List<CategoryLang> categoryLangList, Integer lang) {
        if (CollUtil.isEmpty(categoryLangList)) {
            return null;
        }
        Map<Integer, CategoryLang> map = categoryLangList.stream().filter(item -> Objects.nonNull(item.getLang())).collect(Collectors.toMap(CategoryLang::getLang, o -> o));
        CategoryLang categoryLang = map.get(getLang(map.keySet(), langConfig, lang));
        return categoryLang;
    }



    /**
     * ======================================= 品牌 =======================================
     */

    public void getBrandLang(List<Brand> brandList) {
        if (CollUtil.isEmpty(brandList)) {
            return;
        }
        getBrandAndLang(brandList);
        for (Brand brand : brandList) {
            brand.setBrandLangList(null);
        }
    }

    public void getBrandAndLang(Brand brand) {
        getBrandAndLang(Collections.singletonList(brand));
    }

    public void getBrandAndLang(List<Brand> brands) {
        if (CollUtil.isEmpty(brands)) {
            return;
        }
        LangConfig langConfig = this.getLangConfig();

        List<Long> ids = brands.stream().map(Brand::getBrandId).collect(Collectors.toList());
        List<BrandLang> list = brandLangService.list(new LambdaQueryWrapper<BrandLang>().in(BrandLang::getBrandId , ids));
        Map<Long, List<BrandLang>> langMap = list.stream().collect(Collectors.groupingBy(BrandLang::getBrandId));
        for (Brand brand : brands) {
            List<BrandLang> langList = langMap.get(brand.getBrandId());
            if (CollUtil.isEmpty(langList)) {
                continue;
            }
            Map<Integer, BrandLang> map = langList.stream().filter(item -> Objects.nonNull(item.getLang())).collect(Collectors.toMap(BrandLang::getLang, o -> o));
            BrandLang brandLang = map.get(getLang(map.keySet(), langConfig, I18nMessage.getLang()));
            brand.setName(brandLang.getName());
            brand.setBrandLangList(langList);
        }
    }


    public void getBrandShopVOAndLang(List<BrandShopVO> brands) {
        LangConfig langConfig = this.getLangConfig();
        if (CollUtil.isEmpty(brands)) {
            return;
        }
        List<Long> ids = brands.stream().map(BrandShopVO::getBrandId).collect(Collectors.toList());
        List<BrandLang> list = brandLangService.list(new LambdaQueryWrapper<BrandLang>().in(BrandLang::getBrandId , ids));
        Map<Long, List<BrandLang>> brandLangMap = list.stream().collect(Collectors.groupingBy(BrandLang::getBrandId));
        for (BrandShopVO brand : brands) {
            List<BrandLang> brandLangList = brandLangMap.get(brand.getBrandId());
            if (CollUtil.isEmpty(brandLangList)) {
                continue;
            }
            Map<Integer, BrandLang> map = brandLangList.stream().filter(item -> Objects.nonNull(item.getLang())).collect(Collectors.toMap(BrandLang::getLang, o -> o));
            BrandLang brandLang = map.get(getLang(map.keySet(), langConfig, I18nMessage.getLang()));
            brand.setName(brandLang.getName());
        }
    }



    /**
     * ======================================= 规格 =======================================
     */

    public void getProdPropAndLang(List<ProdProp> prodProps) {
        if (CollUtil.isEmpty(prodProps)) {
            return;
        }
        LangConfig langConfig = this.getLangConfig();

        List<Long> ids = prodProps.stream().map(ProdProp::getPropId).collect(Collectors.toList());
        List<ProdPropLang> list = prodPropLangService.list(new LambdaQueryWrapper<ProdPropLang>().in(ProdPropLang::getPropId , ids));
        Map<Long, List<ProdPropLang>> langMap = list.stream().collect(Collectors.groupingBy(ProdPropLang::getPropId));
        for (ProdProp prodProp : prodProps) {
            List<ProdPropLang> langList = langMap.get(prodProp.getPropId());
            if (CollUtil.isEmpty(langList)) {
                continue;
            }
            Map<Integer, ProdPropLang> map = langList.stream().filter(item -> Objects.nonNull(item.getLang())).collect(Collectors.toMap(ProdPropLang::getLang, o -> o));
            ProdPropLang prodPropLang = map.get(getLang(map.keySet(), langConfig, I18nMessage.getLang()));
            prodProp.setPropName(prodPropLang.getPropName());
            prodProp.setProdPropLangList(langList);
        }
    }

    public void getProdPropAndValueLang(List<ProdProp> prodPropList) {
        if (CollUtil.isEmpty(prodPropList)) {
            return;
        }
        List<ProdPropValue> prodPropValueList = new ArrayList<>();
        for (ProdProp prodProp : prodPropList) {
            if (CollUtil.isEmpty(prodProp.getProdPropValues())) {
                continue;
            }
            prodPropValueList.addAll(prodProp.getProdPropValues());
        }
        this.getProdPropAndLang(prodPropList);
        this.getProdPropValueAndLang(prodPropValueList);
    }

    /**
     * ======================================= 规格值 =======================================
     */
    public void getProdPropValueLang(List<ProdPropValue> prodPropValues) {
        this.getProdPropValueAndLang(prodPropValues);
        for (ProdPropValue prodPropValue : prodPropValues) {
            prodPropValue.setProdPropValueLangList(null);
        }
    }

    private void getProdPropValueAndLang(List<ProdPropValue> prodPropValues) {
        if (CollUtil.isEmpty(prodPropValues)) {
            return;
        }
        LangConfig langConfig = this.getLangConfig();

        List<Long> ids = prodPropValues.stream().map(ProdPropValue::getValueId).collect(Collectors.toList());
        List<ProdPropValueLang> list = prodPropValueLangService.list(new LambdaQueryWrapper<ProdPropValueLang>().in(ProdPropValueLang::getValueId , ids));
        Map<Long, List<ProdPropValueLang>> langMap = list.stream().collect(Collectors.groupingBy(ProdPropValueLang::getValueId));
        for (ProdPropValue prodPropValue : prodPropValues) {
            List<ProdPropValueLang> langList = langMap.get(prodPropValue.getValueId());
            if (CollUtil.isEmpty(langList)) {
                continue;
            }
            Map<Integer, ProdPropValueLang> map = langList.stream().filter(item -> Objects.nonNull(item.getLang())).collect(Collectors.toMap(ProdPropValueLang::getLang, o -> o));
            ProdPropValueLang prodPropValueLang = map.get(getLang(map.keySet(), langConfig, I18nMessage.getLang()));
            prodPropValue.setPropValue(prodPropValueLang.getPropValue());
            prodPropValue.setProdPropValueLangList(langList);
        }
    }


    /**
     * ======================================= 商品参数 =======================================
     */

    public void getProdParameterAndLang(List<ProdParameter> prodParameters) {
        if (CollUtil.isEmpty(prodParameters)) {
            return;
        }
        LangConfig langConfig = this.getLangConfig();

        List<Long> ids = prodParameters.stream().map(ProdParameter::getProdParameterId).collect(Collectors.toList());
        List<ProdParameterLang> list = prodParameterLangService.list(new LambdaQueryWrapper<ProdParameterLang>().in(ProdParameterLang::getProdParameterId , ids));
        Map<Long, List<ProdParameterLang>> langMap = list.stream().collect(Collectors.groupingBy(ProdParameterLang::getProdParameterId));
        for (ProdParameter prodParameter : prodParameters) {
            List<ProdParameterLang> langList = langMap.get(prodParameter.getProdParameterId());
            if (CollUtil.isEmpty(langList)) {
                continue;
            }
            Map<Integer, ProdParameterLang> map = langList.stream().filter(item -> Objects.nonNull(item.getLang())).collect(Collectors.toMap(ProdParameterLang::getLang, o -> o));
            ProdParameterLang prodParameterLang = map.get(getLang(map.keySet(), langConfig, I18nMessage.getLang()));
            prodParameter.setParameterKey(prodParameterLang.getParameterKey());
            prodParameter.setParameterValue(prodParameterLang.getParameterValue());
            prodParameter.setProdParameterLangList(langList);
        }
    }

    public void handleProdParameterLang(List<ProdParameter> prodParameters) {
        if (CollUtil.isEmpty(prodParameters)) {
            return;
        }
        Integer lang = I18nMessage.getLang();
        LangConfig langConfig = this.getLangConfig();
        for (ProdParameter prodParameter : prodParameters) {
            if (CollUtil.isEmpty(prodParameter.getProdParameterLangList())) {
                continue;
            }
            Map<Integer, ProdParameterLang> parameterLangMap = prodParameter.getProdParameterLangList().stream().filter(prodParameterLang -> Objects.nonNull(prodParameterLang.getLang())).collect(Collectors.toMap(ProdParameterLang::getLang, p -> p));
            ProdParameterLang prodParameterLang = parameterLangMap.get(getLang(parameterLangMap.keySet(), langConfig, lang));
            prodParameter.setParameterKey(prodParameterLang.getParameterKey());
            prodParameter.setParameterValue(prodParameterLang.getParameterValue());
        }
    }



    /**
     * ======================================= 出入库商品项 =======================================
     */
    public void getStockBillLogItem(List<StockBillLogItem> stockBillLogItems) {
        if (CollUtil.isEmpty(stockBillLogItems)) {
            return;
        }
        List<Long> prodIds = new ArrayList<>();
        List<Long> skuIds = new ArrayList<>();
        for (StockBillLogItem stockBillLogItem : stockBillLogItems) {
            if (Objects.nonNull(stockBillLogItem.getProdId())) {
                prodIds.add(stockBillLogItem.getProdId());
            }
            if (Objects.nonNull(stockBillLogItem.getSkuId())) {
                skuIds.add(stockBillLogItem.getSkuId());
            }
        }
        Map<Long, ProdLang> prodLangMap = this.getProdLangMap(prodIds);
        Map<Long, SkuLang> skuLangMap = this.getSkuLangMap(skuIds);

        for (StockBillLogItem stockBillLogItem : stockBillLogItems) {
            ProdLang prodLang = prodLangMap.get(stockBillLogItem.getProdId());
            if (Objects.nonNull(prodLang)) {
                stockBillLogItem.setProdName(prodLang.getProdName());
            }
            SkuLang skuLang = skuLangMap.get(stockBillLogItem.getSkuId());
            if (Objects.nonNull(skuLang)) {
                stockBillLogItem.setSkuName(skuLang.getSkuName());
            }
        }
    }


    /**
     * ======================================= 出入库商品项 =======================================
     */

    public void getSupplierProdVOLang(List<SupplierProdVO> supplierProdList) {
        if (CollUtil.isEmpty(supplierProdList)) {
            return;
        }
        List<Long> prodIds = new ArrayList<>();
        List<Long> skuIds = new ArrayList<>();
        for (SupplierProdVO item : supplierProdList) {
            if (Objects.nonNull(item.getProdId())) {
                prodIds.add(item.getProdId());
            }
            if (CollUtil.isEmpty(item.getSkuList())) {
                continue;
            }
            for (SupplierSkuVO supplierSkuVO : item.getSkuList()) {
                skuIds.add(supplierSkuVO.getSkuId());
            }
        }
        Map<Long, ProdLang> prodLangMap = this.getProdLangMap(prodIds);
        Map<Long, SkuLang> skuLangMap = this.getSkuLangMap(skuIds);

        for (SupplierProdVO item : supplierProdList) {
            ProdLang prodLang = prodLangMap.get(item.getProdId());
            if (Objects.nonNull(prodLang)) {
                item.setProdName(prodLang.getProdName());
            }
            if (CollUtil.isEmpty(item.getSkuList())) {
                continue;
            }
            for (SupplierSkuVO supplierSkuVO : item.getSkuList()) {
                SkuLang skuLang = skuLangMap.get(supplierSkuVO.getSkuId());
                if (Objects.nonNull(skuLang)) {
                    supplierSkuVO.setSkuName(skuLang.getSkuName());
                }
            }
        }
    }



    /**
     * ======================================= 赠品 =======================================
     */

    public void getGivewayLang(Giveaway giveaway) {
        this.getGivewayLang(Collections.singletonList(giveaway));
    }
    public void getGivewayLang(List<Giveaway> giveawayList) {
        if (CollUtil.isEmpty(giveawayList)) {
            return;
        }
        List<Long> ids = giveawayList.stream().filter(giveaway -> Objects.nonNull(giveaway.getProdId())).map(Giveaway::getProdId).collect(Collectors.toList());
        Map<Long, ProdLang> prodLangMap = this.getProdLangMap(ids);
        for (Giveaway giveaway : giveawayList) {
            ProdLang prodLang = prodLangMap.get(giveaway.getProdId());
            if (Objects.nonNull(prodLang)) {
                giveaway.setProdName(prodLang.getProdName());
            }
        }
    }



    /**
     * ======================================= 购物车项 =======================================
     */

    public void getShopCartItemDtoLang(List<ShopCartItemDto> shopCartItemDtoList) {
        if (CollUtil.isEmpty(shopCartItemDtoList)) {
            return;
        }
        List<Long> prodIds = new ArrayList<>();
        List<Long> skuIds = new ArrayList<>();
        for (ShopCartItemDto item : shopCartItemDtoList) {
            if (Objects.nonNull(item.getProdId())) {
                prodIds.add(item.getProdId());
            }
            if (Objects.nonNull(item.getSkuId())) {
                skuIds.add(item.getSkuId());
            }
        }
        Map<Long, ProdLang> prodLangMap = this.getProdLangMap(prodIds);
        Map<Long, SkuLang> skuLangMap = this.getSkuLangMap(skuIds);

        for (ShopCartItemDto item : shopCartItemDtoList) {
            ProdLang prodLang = prodLangMap.get(item.getProdId());
            if (Objects.nonNull(prodLang)) {
                item.setProdName(prodLang.getProdName());
            }
            SkuLang skuLang = skuLangMap.get(item.getSkuId());
            if (Objects.nonNull(skuLang)) {
                item.setSkuName(skuLang.getSkuName());
            }
        }
    }



    /**
     * ======================================= 盘点商品 =======================================
     */


    public void getTakeStockProdVOLang(List<TakeStockProdVO> takeStockProdList) {
        if (CollUtil.isEmpty(takeStockProdList)) {
            return;
        }
        List<Long> prodIds = new ArrayList<>();
        List<Long> skuIds = new ArrayList<>();
        for (TakeStockProdVO item : takeStockProdList) {
            if (Objects.nonNull(item.getProdId())) {
                prodIds.add(item.getProdId());
            }
            if (Objects.nonNull(item.getSkuId())) {
                skuIds.add(item.getSkuId());
            }
        }
        Map<Long, ProdLang> prodLangMap = this.getProdLangMap(prodIds);
        Map<Long, SkuLang> skuLangMap = this.getSkuLangMap(skuIds);

        for (TakeStockProdVO item : takeStockProdList) {
            ProdLang prodLang = prodLangMap.get(item.getProdId());
            if (Objects.nonNull(prodLang)) {
                item.setProdName(prodLang.getProdName());
            }
            SkuLang skuLang = skuLangMap.get(item.getSkuId());
            if (Objects.nonNull(skuLang)) {
                item.setSkuName(skuLang.getSkuName());
            }
        }
    }



    /**
     * ======================================= 盘点库存 =======================================
     */

    public void getTakeStockVOLang(List<TakeStockVO> takeStockList) {

        if (CollUtil.isEmpty(takeStockList)) {
            return;
        }
        List<Long> prodIds = new ArrayList<>();
        List<Long> skuIds = new ArrayList<>();
        for (TakeStockVO item : takeStockList) {
            if (CollUtil.isEmpty(item.getTakeStockProdList())) {
                continue;
            }
            for (TakeStockProdVO takeStockProdVO : item.getTakeStockProdList()) {
                if (Objects.nonNull(takeStockProdVO.getProdId())) {
                    prodIds.add(takeStockProdVO.getProdId());
                }
                if (Objects.nonNull(takeStockProdVO.getSkuId())) {
                    skuIds.add(takeStockProdVO.getSkuId());
                }
            }
        }
        Map<Long, ProdLang> prodLangMap = this.getProdLangMap(prodIds);
        Map<Long, SkuLang> skuLangMap = this.getSkuLangMap(skuIds);

        for (TakeStockVO item : takeStockList) {
            if (CollUtil.isEmpty(item.getTakeStockProdList())) {
                continue;
            }
            for (TakeStockProdVO takeStockProdVO : item.getTakeStockProdList()) {
                ProdLang prodLang = prodLangMap.get(takeStockProdVO.getProdId());
                if (Objects.nonNull(prodLang)) {
                    takeStockProdVO.setProdName(prodLang.getProdName());
                }
                SkuLang skuLang = skuLangMap.get(takeStockProdVO.getSkuId());
                if (Objects.nonNull(skuLang)) {
                    takeStockProdVO.setSkuName(skuLang.getSkuName());
                }
            }
        }
    }


    /**
     * ======================================= 出入库记录 =======================================
     */

    public void getStockBillExportParamLang(List<StockBillExportParam> stockBillExportParamList) {
        if (CollUtil.isEmpty(stockBillExportParamList)) {
            return;
        }
        List<Long> prodIds = new ArrayList<>();
        List<Long> skuIds = new ArrayList<>();
        List<Long> stockChangeReasonIds = new ArrayList<>();
        for (StockBillExportParam item : stockBillExportParamList) {
            if (Objects.nonNull(item.getProdId())) {
                prodIds.add(item.getProdId());
            }
            if (Objects.nonNull(item.getSkuId())) {
                skuIds.add(item.getSkuId());
            }
            if (Objects.nonNull(item.getStockChangeReasonId())) {
                stockChangeReasonIds.add(item.getStockChangeReasonId());
            }
        }
        Map<Long, ProdLang> prodLangMap = this.getProdLangMap(prodIds);
        Map<Long, SkuLang> skuLangMap = this.getSkuLangMap(skuIds);
        Map<Long, StockChangeReasonLang> stockChangeReasonLangMap = this.getStockChangeReasonLangMap(skuIds);

        for (StockBillExportParam item : stockBillExportParamList) {
            ProdLang prodLang = prodLangMap.get(item.getProdId());
            if (Objects.nonNull(prodLang)) {
                item.setProdName(prodLang.getProdName());
            }
            SkuLang skuLang = skuLangMap.get(item.getSkuId());
            if (Objects.nonNull(skuLang)) {
                item.setSkuName(skuLang.getSkuName());
            }
            StockChangeReasonLang stockChangeReasonLang = stockChangeReasonLangMap.get(item.getStockChangeReasonId());
            if (Objects.nonNull(stockChangeReasonLang)) {
                item.setReason(stockChangeReasonLang.getReason());
                item.setRemark(stockChangeReasonLang.getRemark());
            }
        }
    }

    /**
     * ======================================= 出入库明细 =======================================
     */
    public void getStockBillLogLang(StockBillLog stockBillLog) {
        this.getStockBillLogLang(Collections.singletonList(stockBillLog));
    }

    public void getStockBillLogLang(List<StockBillLog> stockBillLogList) {
        if (CollUtil.isEmpty(stockBillLogList)) {
            return;
        }
        List<Long> prodIds = new ArrayList<>();
        List<Long> stockChangeReasonIds = new ArrayList<>();
        for (StockBillLog stockBillLog : stockBillLogList) {
            stockChangeReasonIds.add(stockBillLog.getStockChangeReasonId());
            prodIds.add(stockBillLog.getProdId());
        }
        Map<Long, StockChangeReasonLang> stockChangeReasonLangMap = this.getStockChangeReasonLangMap(stockChangeReasonIds);
        Map<Long, ProdLang> prodLangMap = this.getProdLangMap(prodIds);
        for (StockBillLog item : stockBillLogList) {
            ProdLang prodLang = prodLangMap.get(item.getProdId());
            if (Objects.nonNull(prodLang)) {
                item.setProdName(prodLang.getProdName());
            }
            StockChangeReasonLang stockChangeReasonLang = stockChangeReasonLangMap.get(item.getStockChangeReasonId());
            if (Objects.nonNull(stockChangeReasonLang)) {
                item.setReason(stockChangeReasonLang.getReason());
                item.setRemark(stockChangeReasonLang.getRemark());
            }
        }
    }

    /**
     * ======================================= 规格值 =======================================
     */
    public void getStockChangeReasonLang(List<StockChangeReason> stockChangeReasonList) {
        this.getStockChangeReasonAndLang(stockChangeReasonList);
        for (StockChangeReason stockChangeReason : stockChangeReasonList) {
            stockChangeReason.setStockChangeReasonLangList(null);
        }
    }
    public void getStockChangeReasonAndLang(StockChangeReason stockChangeReason) {
        this.getStockChangeReasonAndLang(Collections.singletonList(stockChangeReason));
    }

    public void getStockChangeReasonAndLang(List<StockChangeReason> stockChangeReasonList) {
        if (CollUtil.isEmpty(stockChangeReasonList)) {
            return;
        }
        LangConfig langConfig = this.getLangConfig();

        List<Long> ids = stockChangeReasonList.stream().map(StockChangeReason::getStockChangeReasonId).collect(Collectors.toList());
        List<StockChangeReasonLang> list = stockChangeReasonLangService.list(new LambdaQueryWrapper<StockChangeReasonLang>().in(StockChangeReasonLang::getStockChangeReasonId , ids));
        Map<Long, List<StockChangeReasonLang>> langMap = list.stream().collect(Collectors.groupingBy(StockChangeReasonLang::getStockChangeReasonId));
        for (StockChangeReason stockChangeReason : stockChangeReasonList) {
            List<StockChangeReasonLang> langList = langMap.get(stockChangeReason.getStockChangeReasonId());
            if (CollUtil.isEmpty(langList)) {
                continue;
            }
            Map<Integer, StockChangeReasonLang> map = langList.stream().filter(item -> Objects.nonNull(item.getLang())).collect(Collectors.toMap(StockChangeReasonLang::getLang, o -> o));
            StockChangeReasonLang stockChangeReasonLang = map.get(getLang(map.keySet(), langConfig, I18nMessage.getLang()));
            stockChangeReason.setReason(stockChangeReasonLang.getReason());
            stockChangeReason.setRemark(stockChangeReasonLang.getRemark());
            stockChangeReason.setStockChangeReasonLangList(langList);
        }
    }

    public Map<Long, StockChangeReasonLang> getStockChangeReasonLangMap(List<Long> stockChangeReasonIds) {
        Map<Long, StockChangeReasonLang> stockChangeReasonMap = new HashMap<>();
        if (CollUtil.isEmpty(stockChangeReasonIds)) {
            return stockChangeReasonMap;
        }
        LangConfig langConfig = this.getLangConfig();

        List<StockChangeReasonLang> list = stockChangeReasonLangService.list(new LambdaQueryWrapper<StockChangeReasonLang>().in(StockChangeReasonLang::getStockChangeReasonId , stockChangeReasonIds));
        Map<Long, List<StockChangeReasonLang>> langMap = list.stream().collect(Collectors.groupingBy(StockChangeReasonLang::getStockChangeReasonId));
        for (Long stockChangeReason : stockChangeReasonIds) {
            List<StockChangeReasonLang> langList = langMap.get(stockChangeReason);
            if (CollUtil.isEmpty(langList)) {
                continue;
            }
            Map<Integer, StockChangeReasonLang> map = langList.stream().filter(item -> Objects.nonNull(item.getLang())).collect(Collectors.toMap(StockChangeReasonLang::getLang, o -> o));
            StockChangeReasonLang stockChangeReasonLang = map.get(getLang(map.keySet(), langConfig, I18nMessage.getLang()));
            stockChangeReasonMap.put(stockChangeReason, stockChangeReasonLang);
        }
        return stockChangeReasonMap;
    }

    /**
     * ======================================= 套餐商品 =======================================
     */
    public void getComboProdVOAndLang(List<ComboProdVO> prodList) {
        if (CollUtil.isEmpty(prodList)) {
            return;
        }
        LangConfig langConfig = this.getLangConfig();
        List<Long> ids = prodList.stream().filter(comboProdVO -> Objects.nonNull(comboProdVO.getProdId())).map(ComboProdVO::getProdId).collect(Collectors.toList());
        List<ProdLang> list = prodLangService.list(new LambdaQueryWrapper<ProdLang>().in(ProdLang::getProdId , ids));
        Map<Long, List<ProdLang>> langMap = list.stream().collect(Collectors.groupingBy(ProdLang::getProdId));
        for (ComboProdVO product : prodList) {
            List<ProdLang> langList = langMap.get(product.getProdId());
            if (CollUtil.isEmpty(langList)) {
                continue;
            }
            Map<Integer, ProdLang> map = langList.stream().filter(item -> Objects.nonNull(item.getLang())).collect(Collectors.toMap(ProdLang::getLang, o -> o));
            ProdLang prodLang = map.get(getLang(map.keySet(), langConfig, I18nMessage.getLang()));
            product.setProdName(prodLang.getProdName());
            product.setProdLangList(langList);
        }
    }
    public void handleComboLang(List<ComboVO> comboList) {
        if (CollUtil.isEmpty(comboList)) {
            return;
        }
        List<ComboProdVO> prodList = new ArrayList<>();
        for (ComboVO comboVO : comboList) {
            if (CollUtil.isNotEmpty(comboList)) {
                prodList.addAll(comboVO.getMatchingProds());
            }
            if (Objects.nonNull(comboVO.getMainProd())) {
                prodList.add(comboVO.getMainProd());
            }
        }
        if (CollUtil.isEmpty(prodList)) {
            return;
        }
        Integer lang = I18nMessage.getLang();
        LangConfig langConfig = this.getLangConfig();
        for (ComboProdVO comboProdVO : prodList) {
            if (CollUtil.isEmpty(comboProdVO.getProdLangList())) {
                continue;
            }
            ProdLang prodLang = getProdLang(langConfig, comboProdVO.getProdLangList(), lang);
            comboProdVO.setProdName(prodLang.getProdName());
        }
    }


    /**
     * 获取默认语言
     * @return
     */
    public Integer getDefaultLang() {
        LangConfig lang = this.getLangConfig();
        return lang.getLang();
    }

    public Integer getLang(Set<Integer> langSet) {
        Integer lang = I18nMessage.getLang();
        LangConfig langConfig = getLangConfig();
        return getLang(langSet, langConfig, lang);
    }

    public Integer getLang(Set<Integer> langSet, LangConfig langConfig, Integer lang) {
        boolean defaultLang = Objects.equals(lang, langConfig.getLang());
        if (langSet.contains(lang)) {
            return lang;
        }
        // 如果不包含当前语言，就尝试获取其他的语言信息
        else {
            // 优先默认语言
            if (!defaultLang && langSet.contains(langConfig.getLang())) {
                return langConfig.getLang();
            }
            // 如果没有默认语言，再按尝试从语言列表中或者语言
            else {
                for (LangItemConfig langItemConfig : langConfig.getLangItemList()) {
                    if (langSet.contains(langItemConfig.getLang())) {
                        return langItemConfig.getLang();
                    }
                }
            }
        }

        // 排序，防止每次获取的语言都不一致
        List<Integer> langList = new ArrayList<>(langSet);
        Collections.sort(langList);
        // 如果上面的步骤都无法获取到对应语言，就是该商品拥有的语言已经被删除，这里强制赋值一种
        return langList.get(0);
    }
    public LangConfig getLangConfig() {
        LangConfig langConfig = shopConfig.getLang();
        if (CollUtil.isEmpty(langConfig.getLangItemList())) {
            langConfig.setLangItemList(new ArrayList<>());
        }
        langConfig.getLangItemList().removeIf(langItemConfig -> Objects.isNull(langItemConfig.getHide()) || Objects.equals(langItemConfig.getHide(), 1));
        return langConfig;
    }
}
